#include "StdAfx.h"
#include "DataManager.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CDataManager::CDataManager(void)
{
	InitializeCriticalSection(&m_CriticalSection);
	eatDataSet = nullptr;
	foodAdapter = nullptr;
	areaAdapter = nullptr;
	discountAdapter = nullptr;
	initDataManager();

}

CDataManager::~CDataManager(void)
{
	if (foodAdapter)
	{
		delete foodAdapter;
	}
	if(areaAdapter)
	{
		delete areaAdapter;
	}
	if (eatDataSet)
	{
		delete eatDataSet;
	}
	if (tableAdapter)
	{
		tableAdapter->Update(eatDataSet->Table);
		delete tableAdapter;
	}
	if (preserveAdapter)
	{
		delete preserveAdapter;
	}
	if (orderAdapter)
	{
		delete orderAdapter;
	}

	DeleteCriticalSection(&m_CriticalSection);
}

void CDataManager::initDataManager()
{
	foodAdapter = gcnew FoodTableAdapter();
	eatDataSet = gcnew EaterySystemDataSet();
	areaAdapter = gcnew areaTableAdapter();
	tableAdapter = gcnew TableTableAdapter();
	discountAdapter = gcnew DiscountTableAdapter();
	userAdapter = gcnew UserTableAdapter();
	employeeInfoAdapter = gcnew EmployeeTableAdapter();
	preserveAdapter = gcnew PreserveTableAdapter();
	orderAdapter = gcnew OrderTableAdapter();

	foodAdapter->Fill(eatDataSet->Food);
	areaAdapter->Fill(eatDataSet->area);
	tableAdapter->Fill(eatDataSet->Table);
	userAdapter->Fill(eatDataSet->User);
	preserveAdapter->Fill(eatDataSet->Preserve);

	tableAdapter->initialDesk();
}

int CDataManager::getFoodCount()
{
	return eatDataSet->Food->Rows->Count;
}

void CDataManager::getAreaInfo(vector<areaInfo>& area)
{
	Lock();
	int nAreaCount = eatDataSet->area->Rows->Count;
	area.resize(nAreaCount);
	for (int i = 0; i< nAreaCount; i++)
	{
		areaInfo& newArea = area[i];
		EaterySystemDataSet::areaRow^ tempRow = (EaterySystemDataSet::areaRow^)eatDataSet->area->Rows[i];
		String^ areaName = tempRow->name;
		pin_ptr<const wchar_t> tempChar = PtrToStringChars(areaName);
		memcpy(newArea.areaName,tempChar,((areaName->Length + 1) * 2));
		dataManage::EaterySystemDataSet::TableDataTable^ desktopInArea = tableAdapter->GetDesktopInfo(areaName);
		int desktopCount = desktopInArea->Rows->Count;
		newArea.desktops.resize(desktopCount);
		for (int j = 0; j < desktopCount; j++)
		{
			EaterySystemDataSet::TableRow^ DesktopRow = (EaterySystemDataSet::TableRow^)desktopInArea->Rows[j];
			desktopInfo& newDesktop = newArea.desktops[j];
			String^ desktopName = DesktopRow->id;
			pin_ptr<const wchar_t> tempChar = PtrToStringChars(desktopName);
			memcpy(newDesktop.deskName,tempChar,((desktopName->Length + 1) * 2));
			newDesktop.state = DesktopRow->state;
		}
	}
	UnLock();
}

void CDataManager::addDesktop(const desktopInfo& desktop,wchar_t* areaName)
{
	EaterySystemDataSet::TableRow^ newDesktop = eatDataSet->Table->NewTableRow();
	String ^areastring = gcnew String(areaName);
	newDesktop->areaName = areastring;
	String ^desktopString = gcnew String((wchar_t*)desktop.deskName);
	newDesktop->id = desktopString;
	newDesktop->state = 0;
	eatDataSet->Table->AddTableRow(newDesktop);
	tableAdapter->Update(eatDataSet->Table);
//	tableAdapter->Insert(desktopString,areastring,0);
	delete newDesktop;
	delete areastring;
	delete desktopString;
}

void CDataManager::removeDesktop(const wchar_t* deskName,const wchar_t* areaName)
{
	String ^areastring = gcnew String(areaName);
	String ^desktopString = gcnew String(deskName);
	tableAdapter->DeleteDesktop(desktopString,areastring);
	delete desktopString;
	delete areastring;

}

void CDataManager::addArea(const wchar_t* areaName)
{
	Lock();
	String^ areaString = gcnew String(areaName);
	areaAdapter->InsertQuery(areaString);
	areaAdapter->Fill(eatDataSet->area);
	delete areaString;
	UnLock();
}

void CDataManager::delArea(const wchar_t* areaName)
{
	Lock();
	String^ areaString = gcnew String(areaName);
	areaAdapter->DeleteQuery(areaString);
	areaAdapter->Fill(eatDataSet->area);

	tableAdapter->DeleteDesktopInArea(areaString);
	tableAdapter->Fill(eatDataSet->Table);
	delete areaString;
	UnLock();

}

void CDataManager::getDiscount(vector<discount>& vDiscount,const wchar_t* discountName)
{
	Lock();
	String^ discountString = gcnew String(discountName) ;
	EaterySystemDataSet::DiscountDataTable^ table;
	table = discountAdapter->GetDataByDiscountName(discountString);
	int nCount = table->Rows->Count; 
	vDiscount.resize(nCount);
	for(int i = 0; i < nCount; i++)
	{
		EaterySystemDataSet::DiscountRow^ row = (EaterySystemDataSet::DiscountRow^)table->Rows[i];
		vDiscount[i].nDiscount = (unsigned char)row->discount;
		String^ reason = row->reason;
		pin_ptr<const wchar_t> tempChar = PtrToStringChars(reason );
		memcpy(vDiscount[i].reason,tempChar,((reason ->Length + 1) * 2));

		String^ type = row->foodType;
		pin_ptr<const wchar_t> tempChar2 = PtrToStringChars(type );
		memcpy(vDiscount[i].typeName,tempChar2,((type ->Length + 1) * 2));
	}
	delete table;
	UnLock();
}

void CDataManager::addDiscount(const discountPlan& disPlan)
{
	String^ discountStr = gcnew String(disPlan.discountName);
	for (size_t i = 0; i < disPlan.vDiscount.size(); i++)
	{
		Lock();
		String^ typeStr = gcnew String(disPlan.vDiscount[i].typeName);
		String^ reason = gcnew String(disPlan.vDiscount[i].reason);
		discountAdapter->InsertQuery(typeStr,disPlan.vDiscount[i].nDiscount,reason,discountStr);
		delete typeStr;
		delete reason;
		UnLock();
	}
	delete discountStr;
}

void CDataManager::delDiscount(const wchar_t* discountName)
{
	String^ discountStr = gcnew String(discountName);
	discountAdapter->DeleteDiscount(discountStr);
	delete discountStr;
}
void CDataManager::updateDiscount(const discountPlan& disPlan,const wchar_t* discountName)
{
	String^ discountStr = gcnew String(discountName);
	discountAdapter->DeleteDiscount(discountStr);
	delete discountStr;
	addDiscount(disPlan);
}

void CDataManager::getAccountInfo(vector<userAccount>& account)
{
	Lock();
	int usrCount = eatDataSet->User->Rows->Count;
	account.resize(usrCount);
	for (int i = 0; i< usrCount; i++)
	{
		userAccount& newAccount = account[i];
		EaterySystemDataSet::UserRow^ tempRow = (EaterySystemDataSet::UserRow^)eatDataSet->User->Rows[i];
		String^ userName = tempRow->username;
		pin_ptr<const wchar_t> tempChar = PtrToStringChars(userName);
		memcpy(newAccount.username,tempChar,((userName->Length + 1) * 2));

		String^ passwd = tempRow->passwd;
		tempChar = PtrToStringChars(passwd);
		memcpy(newAccount.passwd,tempChar,((passwd->Length + 1) * 2));

		newAccount.right = tempRow->right;
	}
	UnLock();
}

void CDataManager::getEmployeeShort(employeeShortInfo &shortInfo, const wchar_t* strId)
{
	Lock();
	String^ idStr = gcnew String(strId);
	EaterySystemDataSet::EmployeeDataTable^ pTable = employeeInfoAdapter->GetShortInfo(idStr);
	if (pTable->Rows->Count != 1)
	{
		memset(&shortInfo,0,sizeof(employeeShortInfo));
		UnLock();
		return;
	}
	EaterySystemDataSet::EmployeeRow^ pRow = (EaterySystemDataSet::EmployeeRow^)pTable->Rows[0];

	String^ employName = pRow->name;
	pin_ptr<const wchar_t> tempChar = PtrToStringChars(employName);
	memcpy(shortInfo.employeeName,tempChar,((employName->Length + 1) * 2));

	String^ employId = pRow->id;
	pin_ptr<const wchar_t> idChar = PtrToStringChars(employId);
	memcpy(shortInfo.employeeId,idChar,((employName->Length + 1) * 2));

	UnLock();
}

void CDataManager::SetBookStateReady(const CTime& startTime,const CTime& endTime)
{
	Lock();
	System::DateTime start(startTime.GetYear(),startTime.GetMonth(),startTime.GetDay(),startTime.GetHour(),startTime.GetMinute(),startTime.GetSecond());
	System::DateTime end(endTime.GetYear(),endTime.GetMonth(),endTime.GetDay(),endTime.GetHour(),endTime.GetMinute(),endTime.GetSecond());
	tableAdapter->SetBookReadyState(end,start);
	UnLock();
}

void CDataManager::SetInvidBookState(const CTime& endTime)
{
	Lock();
	System::DateTime end(endTime.GetYear(),endTime.GetMonth(),endTime.GetDay(),endTime.GetHour(),endTime.GetMinute(),endTime.GetSecond());
	tableAdapter->SetInvidBook(end);
	UnLock();
}

void CDataManager::GetPreserveData(vector<bookManagerData>& pData,const CTime& nowTime,const wchar_t* deskName,const wchar_t* areaName)
{
	Lock();
	String ^areastring = gcnew String(areaName);
	String^ deskString = gcnew String(deskName);
	System::DateTime start(nowTime.GetYear(),nowTime.GetMonth(),nowTime.GetDay(),0,0,0);
	System::DateTime end(nowTime.GetYear(),nowTime.GetMonth(),nowTime.GetDay(),23,59,59);
	EaterySystemDataSet::PreserveDataTable^ table = preserveAdapter->GetBookData(deskString,areastring,start,end);
	pData.resize(table->Rows->Count);
	for (int i = 0; i < table->Rows->Count;i++)
	{
		EaterySystemDataSet::PreserveRow^ nowRow = (EaterySystemDataSet::PreserveRow^)table->Rows[i];

		pData[i].m_arriveTime.hour = nowRow->time.Hour;
		pData[i].m_arriveTime.minute = nowRow->time.Minute;
		pData[i].m_arriveTime.second = nowRow->time.Second;

		String^ contact = nowRow->contact;
		pin_ptr<const wchar_t> tempChar = PtrToStringChars(contact);
		memcpy(pData[i].m_contact,tempChar,((contact->Length + 1) * 2));


		pData[i].m_female = nowRow->gender;

		try
		{
			String^ note = nowRow->note;
			tempChar = PtrToStringChars(note);
			memcpy(pData[i].m_note,tempChar,((note->Length + 1) * 2));
		}
		catch (System::Data::StrongTypingException^ )
		{
			memset(pData[i].m_note,0,50 * sizeof(wchar_t));
		}

		try
		{
			String^ vipId = nowRow->VIPid;
			tempChar = PtrToStringChars(vipId);
			memcpy(pData[i].m_vipId,tempChar,((vipId->Length + 1) * 2));
		}
		catch (System::Data::StrongTypingException^ )
		{
			memset(pData[i].m_vipId,0,50 * sizeof(wchar_t));
		}
		
		String^ name = nowRow->name;
		tempChar = PtrToStringChars(name);
		memcpy(pData[i].name,tempChar,((name->Length + 1) * 2));

	}
	UnLock();
}

void CDataManager::addPreserveData(const newBookData& pData)
{
	EaterySystemDataSet::PreserveRow^ newPreserve = eatDataSet->Preserve->NewPreserveRow();
	newPreserve->areaid = gcnew String(pData.param1.m_areaName);
	newPreserve->contact = gcnew String(pData.param2.m_contact);
	newPreserve->gender = pData.param2.m_female;
	newPreserve->name = gcnew String(pData.param2.name);
	newPreserve->note = gcnew String(pData.param2.m_note);
	newPreserve->tableid = gcnew String(pData.param1.m_deskName);
	newPreserve->time = System::DateTime(pData.param1.m_date.year,pData.param1.m_date.month,pData.param1.m_date.day,pData.param2.m_arriveTime.hour,pData.param2.m_arriveTime.minute,pData.param2.m_arriveTime.second);
	newPreserve->VIPid = gcnew String(pData.param2.m_vipId);
	eatDataSet->Preserve->AddPreserveRow(newPreserve);
	preserveAdapter->Update(eatDataSet->Preserve);
	delete newPreserve;
}

void CDataManager::delPreserveData(const CTime& setTime)
{
	preserveAdapter->DeleteQuery(System::DateTime(setTime.GetYear(),setTime.GetMonth(),setTime.GetDay(),setTime.GetHour(),setTime.GetMinute(),setTime.GetSecond()));
}

void CDataManager::getOrder(const INT64& strSerial,Order& vOrder )
{
	EaterySystemDataSet::OrderDataTable^ table = orderAdapter->GetOrderById(strSerial);
	int nOrderCount = table->Rows->Count;
	if(nOrderCount <= 0)
		return;
	EaterySystemDataSet::OrderRow^ orderRow0 = (EaterySystemDataSet::OrderRow^)table->Rows[0];
	String^ areaName = orderRow0->areaName;
	pin_ptr<const wchar_t> CAreaName = PtrToStringChars(areaName);
	memcpy(vOrder.areaName,CAreaName,((areaName->Length + 1) * 2));

	String^ deskName = orderRow0->deskName;
	pin_ptr<const wchar_t> CDeskName = PtrToStringChars(deskName);
	memcpy(vOrder.deskName,CDeskName,((deskName->Length + 1) * 2));

	vOrder.nSerial = strSerial;

	String^ orderEId = orderRow0->orderEmployeeID;
	pin_ptr<const wchar_t> COrderEId = PtrToStringChars(orderEId);
	memcpy(vOrder.orderEmployeeID,COrderEId,((orderEId->Length + 1) * 2));

	vOrder.time.m_date.year = orderRow0->time.Year;
	vOrder.time.m_date.month = orderRow0->time.Month;
	vOrder.time.m_date.day = orderRow0->time.Day;

	vOrder.time.m_time.hour = orderRow0->time.Hour;
	vOrder.time.m_time.minute = orderRow0->time.Minute;
	vOrder.time.m_time.second = orderRow0->time.Second;
	vOrder.fSeverFee = Decimal::ToDouble( orderRow0->serviceFee );

	String^ vipId = orderRow0->VIPid;
	pin_ptr<const wchar_t> CvipId = PtrToStringChars(vipId);
	memcpy(vOrder.vipId,CvipId,((vipId->Length + 1) * 2));

	String^ casherId = orderRow0->cashierID;
	pin_ptr<const wchar_t> ccasherid = PtrToStringChars(casherId);
	memcpy(vOrder.casherId,ccasherid,((casherId->Length + 1) * 2));

	vOrder.vMainOrder.resize(nOrderCount);
	for (int i = 0 ; i < nOrderCount; i++)
	{
		EaterySystemDataSet::OrderRow^ orderRow = (EaterySystemDataSet::OrderRow^)table->Rows[i];
		OrderMain& nowOrder = vOrder.vMainOrder[i];
		nowOrder.bAlarm = orderRow->bAlarm;

		String^ str = orderRow->discountType;
		pin_ptr<const wchar_t> Cstr = PtrToStringChars(str);
		memcpy(nowOrder.discountType,Cstr,((str->Length + 1) * 2));

		str = orderRow->foodid;
		Cstr = PtrToStringChars(str);
		memcpy(nowOrder.foodId,Cstr,((str->Length + 1) * 2));

		EaterySystemDataSet::FoodDataTable^ foodTable = foodAdapter->GetDataById(orderRow->foodid);
		EaterySystemDataSet::FoodRow^ foodRow = (EaterySystemDataSet::FoodRow^ )foodTable->Rows[0];
		str = foodRow->name;
		Cstr = PtrToStringChars(str);
		memcpy(nowOrder.foodName,Cstr,((str->Length + 1) * 2));

		nowOrder.fPrice = Decimal::ToDouble(foodRow->price);

		str = orderRow->more;
		Cstr = PtrToStringChars(str);
		memcpy(nowOrder.more,Cstr,((str->Length + 1) * 2));
		
		nowOrder.nNum = orderRow->number; 
		nowOrder.fDiscount = orderRow->fDiscount;
	}
}

void CDataManager::delOrder(const INT64& strSerial)
{
	orderAdapter->delOrder(strSerial);
}

void CDataManager::addOrder(const Order& vOrder,const INT64& strSerial)
{
	for (size_t i = 0; i < vOrder.vMainOrder.size(); i++)
	{
		System::String^  foodid = gcnew String(vOrder.vMainOrder[i].foodId); 
		EaterySystemDataSet::FoodDataTable^ foodTable = foodAdapter->GetDataById(foodid);
		if (foodTable->Rows->Count <= 0)
		{
			delete foodid;
			continue;
		}

		System::String^  areaName = gcnew String(vOrder.areaName); 
		System::Int32 number= vOrder.vMainOrder[i].nNum; 
		System::String^  orderEmployeeID = gcnew String(vOrder.orderEmployeeID) ;
		System::DateTime time = DateTime(vOrder.time.m_date.year,vOrder.time.m_date.month,vOrder.time.m_date.day,vOrder.time.m_time.hour,vOrder.time.m_time.minute,vOrder.time.m_time.second); 
		System::String^  deskName = gcnew String(vOrder.deskName);
		System::String^  discountType = gcnew String(vOrder.vMainOrder[i].discountType) ;
		System::Decimal  serviceFee = Decimal(vOrder.fSeverFee); 
		System::String^  VIPid = gcnew String(vOrder.vipId) ;
		System::String^  cashierID = gcnew String(vOrder.casherId);
		System::Boolean bAlarm = vOrder.vMainOrder[i].bAlarm;
		System::String^  more = gcnew String(vOrder.vMainOrder[i].more); 
		System::Int64 setId = strSerial;
		orderAdapter->addOrder(areaName,foodid,number,orderEmployeeID,time,false,deskName,discountType,serviceFee,VIPid,cashierID,bAlarm,more,strSerial,vOrder.vMainOrder[i].fDiscount);
		delete areaName;
		delete foodid;
		delete orderEmployeeID;
		delete deskName;
		delete discountType;
		delete VIPid;
		delete cashierID;
		delete more;
	}
}

void CDataManager::setDesktopState(const wchar_t* areaName,const wchar_t* deskName,int nState)
{
	System::String^  area = gcnew String(areaName); 
	System::String^  desk = gcnew String(deskName); 
	tableAdapter->setState(nState,area,desk);
	delete area;
	delete desk;
}
//void CDataManager::updateOrder(const INT64& strSerial,const Order& vOrder)
//{
//	delOrder(strSerial);
//	addOrder(vOrder,strSerial);
//}

foodParam CDataManager::getFoodParam(const wchar_t* str,bool isId)
{
	Lock();
	foodParam food;
	memset(&food,0,sizeof(foodParam));
	if (isId)
	{
		memcpy(food.id,str,50 * sizeof(wchar_t));
		String^ id = gcnew String(str);
		EaterySystemDataSet::FoodDataTable^ table = foodAdapter->GetDataById(id);
		if (table->Rows->Count > 0)
		{
			EaterySystemDataSet::FoodRow^ row = (EaterySystemDataSet::FoodRow^)table->Rows[0];
			String^ name = row->name;
			pin_ptr<const wchar_t> tempChar = PtrToStringChars(name);
			memcpy(food.name,tempChar,((name->Length + 1) * 2));
			
			food.price = Decimal::ToDouble(row->price);

			String^ abbr = row->key;
			pin_ptr<const wchar_t> abbrC = PtrToStringChars(abbr);
			memcpy(food.abbr,abbrC,((abbr->Length + 1) * 2));

			name = row->type;
			tempChar = PtrToStringChars(name);
			memcpy(food.foodType,tempChar,((name->Length + 1) * 2));

		}
	}
	else
	{
		memcpy(food.abbr,str,50 * sizeof(wchar_t));
		String^ abbr = gcnew String(str);
		
		EaterySystemDataSet::FoodDataTable^ table = foodAdapter->GetDataByAbbr(abbr);
		if (table->Rows->Count > 0)
		{
			EaterySystemDataSet::FoodRow^ row = (EaterySystemDataSet::FoodRow^)table->Rows[0];
			String^ name = row->name;
			pin_ptr<const wchar_t> tempChar = PtrToStringChars(name);
			memcpy(food.name,tempChar,((name->Length + 1) * 2));
			food.price = Decimal::ToDouble(row->price);

			String^ id = row->id;
			pin_ptr<const wchar_t> idC = PtrToStringChars(id);
			memcpy(food.id,idC,((id->Length + 1) * 2));
		}
	}
	UnLock();
	return food;
}
